package la.iok.hzsvn.lewin.movie.controller;

import la.iok.hzsvn.lewin.movie.core.Token;
import la.iok.hzsvn.lewin.movie.core.model.MovieVo;
import la.iok.hzsvn.lewin.movie.entity.Movie;
import la.iok.hzsvn.lewin.movie.model.MovieDeleteContext;
import la.iok.hzsvn.lewin.movie.model.MovieParam;
import la.iok.hzsvn.lewin.movie.service.MovieAssistFileService;
import la.iok.hzsvn.lewin.movie.service.MovieCoverFileService;
import la.iok.hzsvn.lewin.movie.service.MovieInstanceService;
import la.iok.hzsvn.lewin.movie.service.MovieService;
import la.iok.hzsvn.lewin.mybatis.model.PageVo;
import la.iok.hzsvn.share.annotations.Nullable;
import la.iok.hzsvn.share.response.ListDataResponse;
import la.iok.hzsvn.share.response.OperatorResponse;
import la.iok.hzsvn.share.response.OperatorResponses;
import la.iok.hzsvn.share.response.SingleDataResponse;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;

@RestController
@RequestMapping("movies")
public class MovieController {
    private final MovieService movieService;
    private final MovieCoverFileService movieCoverFileService;
    private final MovieAssistFileService movieAssistFileService;
    private final MovieInstanceService movieInstanceService;

    public MovieController(MovieService movieService,
                           MovieCoverFileService movieCoverFileService,
                           MovieAssistFileService movieAssistFileService, MovieInstanceService movieInstanceService) {
        this.movieService = movieService;
        this.movieCoverFileService = movieCoverFileService;
        this.movieAssistFileService = movieAssistFileService;
        this.movieInstanceService = movieInstanceService;
    }

    @PostMapping
    public OperatorResponse save(@RequestHeader Token token, @RequestBody MovieParam movieParam){
        movieService.save(token,movieParam);
        return OperatorResponses.success();
    }
    @PutMapping("{id}")
    public OperatorResponse update(@RequestHeader Token token, @PathVariable Long id, @RequestBody MovieParam movieParam){
        movieService.update(id,token,movieParam);
        return OperatorResponses.success();
    }
    @GetMapping("{id}")
    public SingleDataResponse<MovieVo> movieDetail(@RequestHeader Token token, @PathVariable Long id){
        Movie movie = movieService.validate(token,id);
        return new SingleDataResponse<>(movieService.po2vo(movie));
    }
    @GetMapping
    public SingleDataResponse<PageVo<MovieVo>> page(
            int page, int limit, @Nullable String name, @Nullable String author,
            @Nullable String tag, @Nullable Integer minPlayers, @Nullable Integer maxPlayers,
            @Nullable Integer minDuration, @Nullable Integer maxDuration){
        PageVo<MovieVo> data = movieService.page(page,limit,name,author,tag,minPlayers,maxPlayers,minDuration,maxDuration);
        return new SingleDataResponse<>(data);
    }

    /**
     * 上传剧本封面
     * @param token 操作用户
     * @param id 剧本id
     * @param file 封面文件
     * @return 操作结果
     */
    @PostMapping("{id}/cover")
    public OperatorResponse cover(@RequestHeader Token token,@PathVariable Long id,MultipartFile file,String path){
        movieCoverFileService.uploadCover(token,id,file,path);
        return OperatorResponses.success();
    }

    /**
     * 获取封面图的文件摘要
     * @param token 操作用户
     * @param id 剧本id
     * @return 文件摘要
     */
    @GetMapping("{id}/cover/digest")
    public SingleDataResponse<String> coverDigest(@RequestHeader Token token,@PathVariable Long id){
        Movie movie = movieService.validate(token,id);
        SingleDataResponse<String> res = new SingleDataResponse<>();
        res.setData(movieCoverFileService.digest(movie.getCoverFileId()));
        return res;
    }

    /**
     * 获取封面图的存储路径
     * @param token 操作用户
     * @param id 剧本id
     * @return 文件摘要
     */
    @GetMapping("{id}/cover/storePath")
    public SingleDataResponse<String> coverStorePath(@RequestHeader Token token,@PathVariable Long id){
        Movie movie = movieService.validate(token,id);
        SingleDataResponse<String> res = new SingleDataResponse<>();
        res.setData(movieCoverFileService.storePath(movie.getCoverFileId()));
        return res;
    }

    @GetMapping("{id}/cover")
    public void downloadCover(@RequestHeader Token token, HttpServletResponse response,@PathVariable Long id){
        movieCoverFileService.downloadFile(token,response,id);
    }

    /**
     * 上传剧本手册
     * @param token 操作用户
     * @param id 剧本id
     * @param file 剧本手册文件
     * @param path 文件存储路径,相对剧本根目录
     * @return 操作结果
     */
    @PostMapping("{id}/assist")
    public OperatorResponse assist(@RequestHeader Token token,@PathVariable Long id,MultipartFile file,String path){
        movieAssistFileService.uploadAssist(token,id,file,path);
        return OperatorResponses.success();
    }

    /**
     * 获取剧本手册摘要
     * @param token 操作用户
     * @param id 剧本id
     * @return 文件摘要
     */
    @GetMapping("{id}/assist/digest")
    public SingleDataResponse<String> assistDigest(@RequestHeader Token token,@PathVariable Long id){
        Movie movie = movieService.validate(token,id);
        return OperatorResponses.stringSingleDataResponse(movieAssistFileService.digest(movie.getAssistFileId()));
    }

    /**
     * 获取剧本手册存储路径
     * @param token 操作用户
     * @param id 剧本id
     * @return 文件摘要
     */
    @GetMapping("{id}/assist/storePath")
    public SingleDataResponse<String> assistStorePath(@RequestHeader Token token,@PathVariable Long id){
        Movie movie = movieService.validate(token,id);
        return OperatorResponses.stringSingleDataResponse(movieAssistFileService.storePath(movie.getAssistFileId()));
    }

    /**
     * 下载剧本手册
     * @param token 操作用户
     * @param response 客户端响应
     * @param id 剧本id
     */
    @GetMapping("{id}/assist")
    public void downloadAssist(@RequestHeader Token token, HttpServletResponse response,@PathVariable Long id){
        movieAssistFileService.downloadFile(token,response,id);
    }

    /**
     * 上传剧本手册
     * @param token 操作用户
     * @param id 剧本id
     * @return 操作结果
     */
    @DeleteMapping("{id}/assist")
    public OperatorResponse deleteAssist(@RequestHeader Token token,@PathVariable Long id){
        movieAssistFileService.clearAssist(token,id);
        return OperatorResponses.success();
    }

    /**
     * 剧本上线
     * @param token 操作用户
     * @param id 剧本id
     */
    @PutMapping("{id}/online")
    public OperatorResponse online(@RequestHeader Token token,@PathVariable Long id){
        movieInstanceService.online(token,id);
        return OperatorResponses.success();
    }

    /**
     * 剧本下线
     * @param token 操作用户
     * @param id 剧本id
     * @return 操作结果
     */
    @PutMapping("{id}/offline")
    public OperatorResponse offline(@RequestHeader Token token,@PathVariable Long id){
        movieInstanceService.offline(token,id);
        return OperatorResponses.success();
    }

    /**
     * 更新剧本等级
     * @param token 操作用户
     * @param id 剧本id
     * @param movieLevelId 剧本等级id
     * @return 操作结果
     */
    @PutMapping("{id}/level/{movieLevelId}")
    public OperatorResponse updateLevel(@RequestHeader Token token,@PathVariable Long id,@PathVariable Long movieLevelId){
        movieInstanceService.updateLevel(token,id,movieLevelId);
        return OperatorResponses.success();
    }

    /**
     * 删除剧本。只有未发布的剧本才能删除
     * @param token 操作用户
     * @param id 剧本id
     * @return 操作结果
     */
    @DeleteMapping("{id}")
    public OperatorResponse delete(@RequestHeader Token token, @PathVariable Long id){
        MovieDeleteContext ctx = movieInstanceService.deleteMovie(token,id);
        movieInstanceService.cleanMovieFile(ctx);
        return OperatorResponses.success();
    }

    /**
     * 查询剧本的历史版本列表
     * @param token 操作用户,目前必须是Admin
     * @param id 剧本id
     * @return 剧本的历史版本列表
     */
    @GetMapping("{id}/versions")
    public ListDataResponse<MovieVo> versions(@RequestHeader Token token, @PathVariable Long id){
        return new ListDataResponse<>(movieInstanceService.publishes(token, id));
    }
}
